from rest_framework import viewsets, status, permissions
from rest_framework.response import Response
from rest_framework.decorators import action
from io import BytesIO
import pandas as pd
from django.http import HttpResponse
import logging

from ..models import CommissionCategory, User
from ..serializers import CommissionCategorySerializer

logger = logging.getLogger(__name__)

class IsAdminUserOrReadOnly(permissions.BasePermission):
    """自定义权限：非管理员用户只能查看，不能修改"""
    
    def has_permission(self, request, view):
        if request.method in permissions.SAFE_METHODS:
            return True
        
        # 检查用户是否是管理员
        return request.user and request.user.is_authenticated and hasattr(request.user, 'role') and request.user.role == 1

class CommissionCategoryViewSet(viewsets.ModelViewSet):
    """提成分类视图集"""
    queryset = CommissionCategory.objects.all()
    serializer_class = CommissionCategorySerializer
    permission_classes = [IsAdminUserOrReadOnly]
    
    def get_queryset(self):
        """实现查询过滤"""
        queryset = super().get_queryset()
        
        # 获取查询参数
        commission_category = self.request.query_params.get('commission_category', None)
        
        # 应用过滤条件
        if commission_category:
            queryset = queryset.filter(commission_category__icontains=commission_category)
            
        return queryset
    
    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出提成分类数据为Excel"""
        queryset = self.get_queryset()
        
        # 创建一个空的DataFrame
        df = pd.DataFrame()
        
        # 添加所需列
        df['分类ID'] = [category.id for category in queryset]
        df['提成分类'] = [category.commission_category for category in queryset]
        df['提成比例'] = [category.commission_ratio for category in queryset]
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='提成分类数据', index=False)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=提成分类数据.xlsx'
        
        return response 
        
    @action(detail=False, methods=['get'])
    def import_template(self, request):
        """下载提成分类导入模板"""
        # 创建一个空的DataFrame
        df = pd.DataFrame(columns=['提成分类名称*', '提成比例(%)*'])
        
        # 添加示例数据行
        df.loc[0] = ['标准提成(必填且唯一)', '10']
        df.loc[1] = ['高级提成', '20']
        
        # 添加说明行
        df.loc[2] = ['', '提成比例请以百分比形式填写，如10%填写10']
        
        # 创建一个字节流
        output = BytesIO()
        
        # 将DataFrame写入Excel
        with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
            df.to_excel(writer, sheet_name='提成分类导入模板', index=False)
            
            # 获取工作簿和工作表
            workbook = writer.book
            worksheet = writer.sheets['提成分类导入模板']
            
            # 添加格式
            header_format = workbook.add_format({
                'bold': True,
                'bg_color': '#D9EAD3',
                'border': 1
            })
            
            # 设置列宽
            worksheet.set_column('A:A', 25)
            worksheet.set_column('B:B', 25)
            
            # 应用格式到表头
            for col_num, value in enumerate(df.columns.values):
                worksheet.write(0, col_num, value, header_format)
                
            # 添加说明
            notes_format = workbook.add_format({
                'italic': True,
                'font_color': '#808080'
            })
            
            # 在底部添加说明
            worksheet.write(5, 0, '注意事项:', workbook.add_format({'bold': True}))
            worksheet.write(6, 0, '1. 带*的字段为必填项', notes_format)
            worksheet.write(7, 0, '2. 提成分类名称必须唯一，系统会自动检查是否存在重复', notes_format)
            worksheet.write(8, 0, '3. 提成比例必须是大于0的数字', notes_format)
            
        # 设置文件指针到开始
        output.seek(0)
        
        # 创建响应
        response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
        response['Content-Disposition'] = 'attachment; filename=提成分类导入模板.xlsx'
        
        return response
        
    @action(detail=False, methods=['post'])
    def import_data(self, request):
        """导入提成分类数据"""
        # 检查是否有管理员权限
        if not (request.user and request.user.is_authenticated and hasattr(request.user, 'role') and request.user.role == 1):
            return Response({'success': False, 'message': '没有权限执行此操作'}, status=status.HTTP_403_FORBIDDEN)
            
        file = request.FILES.get('file')
        if not file:
            return Response({'success': False, 'message': '请上传文件'}, status=status.HTTP_400_BAD_REQUEST)
        
        # 检查文件类型
        if not file.name.endswith(('.xlsx', '.xls')):
            return Response({'success': False, 'message': '只支持Excel文件(.xlsx或.xls)'}, status=status.HTTP_400_BAD_REQUEST)
        
        try:
            # 读取Excel文件
            df = pd.read_excel(file)
            
            # 验证必要的列是否存在
            required_columns = ['提成分类名称*', '提成比例(%)*']
            for column in required_columns:
                if column not in df.columns:
                    return Response({'success': False, 'message': f'导入文件缺少必要的列：{column}'}, status=status.HTTP_400_BAD_REQUEST)
            
            # 重命名列以匹配模型字段
            column_mapping = {
                '提成分类名称*': 'commission_category',
                '提成比例(%)*': 'commission_ratio_percent'
            }
            df = df.rename(columns=column_mapping)
            
            # 验证提成分类名称是否为空
            if df['commission_category'].isnull().any():
                return Response({'success': False, 'message': '提成分类名称不能为空'}, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证提成分类名称是否有重复（在导入数据中）
            duplicate_names = df[df.duplicated('commission_category', keep=False)]['commission_category'].unique()
            if len(duplicate_names) > 0:
                duplicates_str = ', '.join(duplicate_names)
                return Response({
                    'success': False, 
                    'message': f'导入数据中存在重复的提成分类名称: {duplicates_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证提成分类名称是否与数据库中的分类重复
            existing_names = []
            for name in df['commission_category']:
                if CommissionCategory.objects.filter(commission_category=name).exists():
                    existing_names.append(name)
            
            if existing_names:
                existing_str = ', '.join(existing_names)
                return Response({
                    'success': False, 
                    'message': f'以下提成分类名称已存在于数据库中: {existing_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 验证提成比例是否有效
            invalid_ratios = []
            for idx, row in df.iterrows():
                ratio = row['commission_ratio_percent']
                if pd.isna(ratio) or not isinstance(ratio, (int, float)) or ratio <= 0:
                    invalid_ratios.append(f"第{idx+1}行: {ratio}")
            
            if invalid_ratios:
                invalid_str = ', '.join(invalid_ratios)
                return Response({
                    'success': False, 
                    'message': f'以下提成比例无效（必须是大于0的数字）: {invalid_str}'
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 开始导入数据
            imported_count = 0
            for _, row in df.iterrows():
                data = {
                    'commission_category': row['commission_category'],
                    'commission_ratio': float(row['commission_ratio_percent']) / 100  # 转换为小数
                }
                
                # 创建提成分类记录
                serializer = self.get_serializer(data=data)
                serializer.is_valid(raise_exception=True)
                serializer.save()
                imported_count += 1
                
            return Response({
                'success': True,
                'message': f'成功导入{imported_count}条提成分类记录',
                'imported_count': imported_count
            })
        
        except Exception as e:
            logger.error(f"导入提成分类数据失败: {str(e)}")
            return Response({'success': False, 'message': f'导入失败: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def update(self, request, *args, **kwargs):
        """更新提成分类"""
        try:
            instance = self.get_object()
            logger.info(f"更新提成分类 - ID: {instance.id}, 请求数据: {request.data}")
            
            # 验证和处理数据
            serializer = self.get_serializer(instance, data=request.data, partial=kwargs.get('partial', False))
            
            if not serializer.is_valid():
                logger.error(f"提成分类数据验证失败: {serializer.errors}")
                return Response({
                    'message': '数据验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 保存更新
            self.perform_update(serializer)
            
            logger.info(f"提成分类更新成功 - ID: {instance.id}")
            return Response({
                'message': '提成分类更新成功',
                'data': serializer.data
            })
            
        except Exception as e:
            logger.exception(f"更新提成分类时发生错误: {str(e)}")
            return Response({
                'message': f'更新失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def create(self, request, *args, **kwargs):
        """创建提成分类"""
        try:
            logger.info(f"创建提成分类 - 请求数据: {request.data}")
            
            # 验证和处理数据
            serializer = self.get_serializer(data=request.data)
            
            if not serializer.is_valid():
                logger.error(f"提成分类数据验证失败: {serializer.errors}")
                return Response({
                    'message': '数据验证失败',
                    'errors': serializer.errors
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 保存
            self.perform_create(serializer)
            
            logger.info(f"提成分类创建成功 - ID: {serializer.data.get('id')}")
            return Response({
                'message': '提成分类创建成功',
                'data': serializer.data
            }, status=status.HTTP_201_CREATED)
            
        except Exception as e:
            logger.exception(f"创建提成分类时发生错误: {str(e)}")
            return Response({
                'message': f'创建失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) 